/**
 * 20220124:created by jordia
 */
import {Object3D, Color, PlaneGeometry, MeshBasicMaterial, Mesh} from "three";
import Text from "../graphic/text";

const DEFAULT_STYLE= {
    fontSize: 16,
    color: new Color(0, 0, 0),
    fontFamily: 'Arial',
    fontStyle: 'normal',
    vivid: 1,
    rowLength: 60,
};
const GEO=new PlaneGeometry(1,1,1,1);

/**
 * debug info panel
 *
 * @param values{object} optional parameters
 *      {
 *          style:DEFAULT_STYLE, {object} parameter object for text(see Text for more detail)
 *          maxCount:20, {number} maximum number of messages to display(at the same time)
 *      }
 */
export default class XRMessage extends Object3D{
    constructor(values={}){
        super();
        this._init(values);
    }

    //..............................................public...................................................

    /**
     * display new message or not
     * @param bol
     */
    set active(bol){
        this._enabled=bol;
    }

    /**
     * print message
     * @param ms
     */
    log(...ms){
        if(!this._enabled)return;
        this._text.text=this._convertMsg(ms);

        let m=new MeshBasicMaterial({
            color:new Color(1,1,1),
            transparent:true,
            depthTest:false,
            map:this._text.material.map,
        });
        let msg=new Mesh(GEO,m);
        msg.scale.copy(this._text.scale);

        this.add(msg);
        this._msgList.unshift(msg);
        this._alignMsg();
    }

    /**
     * clear exist message
     */
    clear(){
        for(let msg of this._msgList){
            this.remove(msg);
            this._destroyMsg(msg);
        }
        this._msgList.length=0;
    }

    //..............................................private..................................................

    _convertMsg(ms){
        this._id++;
        let string=this._id+':';
        for(let m of ms){
            switch (typeof m) {
                case 'object':
                    string+=JSON.stringify(m);
                    break;
                case 'boolean':
                    string+=JSON.stringify(m);
                    break;
                default:
                    string+=m;
            }
        }
        return string;
    }
    _alignMsg(){
        for(let i=0;i<this._msgList.length;i++){
            let cm=this._msgList[i];
            if(i<this._maxCount){
                cm.position.y=-i*0.5;
            }else{
                this.remove(cm);
                this._destroyMsg(cm);
            }
        }
        if(this._msgList.length<this._maxCount)return;
        this._msgList.splice(this._maxCount,this._msgList.length-this._maxCount);
    }
    _destroyMsg(msg){
        if(msg.material.map)msg.material.map.dispose();
        msg.material.dispose();
    }
    _init(values){
        this._initVariable(values);
    }
    _initVariable(values){
        this._msgList=[];
        values.style=values.style||{};
        for(let k in DEFAULT_STYLE){
            if(!values.style.hasOwnProperty(k)){
                values.style[k]=DEFAULT_STYLE[k];
            }
        }
        this._maxCount=Math.max(values.maxCount||20,1);
        this._id=0;
        this._enabled=true;
        this._text=new Text(values.style);
    }
}